use reqwest;
use reqwest::header::{HeaderValue, AUTHORIZATION};
use serde_json::json;
use serde_json::Value;
use std::error::Error;
use std::fmt::format;
use std::fs::{self, File, OpenOptions};
use std::io::prelude::*;
use std::io::Cursor;
use std::io::Write;
use std::process::Command;
use tauri::{command, Manager};
use tokio;
use tokio::time::error;
use xml::reader::XmlEvent;
use xml::EventReader;

// deepseek-coder模型接口(第一次)
pub async fn deepseek_coder_api_first(
    language: &str,
    input_code: &str,
) -> Result<(String, String), Box<dyn Error>> {
    let mut result_code = String::new();
    let mut result_thoughts = String::new();
    //模型对话接口
    let client = reqwest::Client::new();
    let api_endpoint = "http://10.10.1.215:8000/code_trans/invoke/";

    let json_body = json!({
        "input" : {
        "language": language,
        "input_code": input_code
        }
    });

    // 使用 reqwest 库发送 POST 请求
    let response = client
        .post(api_endpoint)
        .header("Content-Type", "application/json")
        .json(&json_body)
        .send()
        .await?;

    //模型对话输出
    println!("\n模型对话第一次输出");
    // 检查响应状态码
    if response.status().is_success() {
        // 读取响应体
        let body = response.text().await?;
        let json_value: Value = serde_json::from_str(&body).unwrap();

        // 提取消息内容
        let output_code = json_value["output"]["output_code"].as_str().unwrap();
        let thoughts = json_value["output"]["thoughts"].as_str().unwrap();

        println!("First Output Code: {}", output_code);
        println!("First Thoughts: {}", thoughts);
        result_code = output_code.to_owned();
        result_thoughts = thoughts.to_owned();
    } else {
        println!("Request failed with status code: {}", response.status());
    }

    Ok((result_code, result_thoughts))
}

// deepseek-coder模型接口(第二次)
pub async fn deepseek_coder_api_second(
    language: &str,       //语言
    input_code: &str,     //输入代码
    thoughts: &str,       //第一次产生的thoughts
    model_response: &str, //第一次模型生成
    std_error: &str,      //第一次错误信息
) -> Result<String, Box<dyn Error>> {
    let mut result_code = String::new();
    //模型对话接口
    let client = reqwest::Client::new();
    let api_endpoint = "http://10.10.1.215:8000/code_trans_debug/invoke/";

    let json_body = json!({
        "input" : {
        "language": language,
        "input_code": input_code,
        "thoughts": thoughts,
        "model_response": model_response,
        "std_error": std_error
        }
    });

    // 使用 reqwest 库发送 POST 请求
    let response = client
        .post(api_endpoint)
        .header("Content-Type", "application/json")
        .json(&json_body)
        .send()
        .await?;

    //模型对话输出
    println!("\n模型对话第二次输出");
    // 检查响应状态码
    if response.status().is_success() {
        // 读取响应体
        let body = response.text().await?;
        let json_value: Value = serde_json::from_str(&body).unwrap();
        // println!("second_body{}", body);
        // 提取消息内容
        let output_code = json_value["output"].as_str().unwrap();

        println!("Second Output Code: {}", output_code);
        result_code = output_code.to_owned();
    } else {
        println!("Request failed with status code: {}", response.status());
    }

    Ok(result_code)
}

//验证全过程+检查是否转换正确+如果不正确则改正一次
pub async fn c2rust_translation(
    language: &str,
    code_content: &str,
) -> Result<String, Box<dyn Error>> {
    let mut result = String::new();
    let mut result_thoughts = String::new();

    //调用api
    match deepseek_coder_api_first(language, code_content).await {
        Ok((code, thoughts)) => {
            result = code;
            result_thoughts = thoughts;
        }
        Err(err) => {
            eprintln!("api调用出错: {}", err);
            // Err(err)
        }
    }
    let env_path = "/var/tmp/unsafe_team_test_env";
    let path = "/var/tmp/unsafe_team_test_env/src/main.rs";
    if fs::metadata(env_path).is_err() {
        create_test_env();
    }
    // 打开文件并写入内容
    match File::create(path) {
        Ok(mut file) => match file.write_all(result.as_bytes()) {
            Ok(_) => {
                println!("Successfully wrote to file");
            }
            Err(e) => eprintln!("Error writing to file: {}", e),
        },
        Err(e) => eprintln!("Error creating file: {}", e),
    }
    let mut output_message = String::new();
    match command_run() {
        Ok(output) => {
            println!("Command executed successfully");
            println!("Output: {}", output);
            output_message = output;
        }
        Err(err) => {
            eprintln!("Error executing command: {}", err);
        }
    }
    if output_message.contains("error") {
        println!("大模型返回的结果有错，处理错误信息");
        match deepseek_coder_api_second(
            language,
            code_content,
            &result_thoughts,
            &result,
            &output_message,
        )
        .await
        {
            Ok(second_result) => {
                result = second_result;
            }
            Err(err) => {
                eprintln!("api调用出错: {}", err);
                // Err(err)
            }
        }
    }
    Ok(result)
}

//创建rust环境
pub fn create_test_env() {
    let output = Command::new("cargo")
        .args(&["new", "unsafe_team_test_env"])
        .current_dir("/var/tmp") // 指定目录路径
        .output()
        .expect("failed to execute process");

    if output.status.success() {
        println!("测试环境创建成功");
        // 进行其他测试环境初始化操作，比如复制 Rust 代码到 main.rs 文件中等
    } else {
        println!("测试环境创建失败");
    }

    //将一些依赖包写入toml
    let cargo_toml_path = "/var/tmp/unsafe_team_test_env/Cargo.toml";
    let mut toml_file = OpenOptions::new()
        .write(true)
        .append(true)
        .open(cargo_toml_path)
        .expect("failed to open Cargo.toml");

    let toml_crate = String::from("memmap = \"0.7.0\"\nlibc = \"0.2.153\"\ntokio = \"0.1\"\naes = \"0.7.4\"\nblock-modes = \"0.8.1\"\nblock-padding = \"0.2.1\"\nhex = \"0.4.3\"\nsignal-hook = \"0.3\"");
    toml_file
        .write_all(toml_crate.as_bytes())
        .expect("failed to write crate entry to Cargo.toml");
}

pub fn command_run() -> std::io::Result<String> {
    println!("执行cargo run 测试");
    // 创建命令对象并设置命令和参数
    let output = Command::new("timeout")
        .arg("10s")
        .arg("cargo")
        .arg("run")
        .current_dir("/var/tmp/unsafe_team_test_env")
        .output()?;

    // 检查命令的执行结果
    if output.status.success() {
        let stdout = String::from_utf8(output.stdout).unwrap();
        // println!("Cargo run output:\n{}", stdout);
        Ok(stdout)
    } else {
        let stderr = String::from_utf8(output.stderr).unwrap();
        // eprintln!("Cargo run error:\n{}", stderr);
        Ok(stderr)
    }
}
